﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;

namespace ElanReader
{
    public class ElanReader
    {
        private Dictionary<string, string> myTimeStamps;
        private List<string> _mediaURL;
        private XmlDocument xmlDoc;
        private List<Segment> _listOfTransciption;
        private List<Segment> _listOfEnverment;
        private List<Segment> _listOfSpeaker;
        private List<Segment> _listOfStoryTopic;
        private List<Segment> _listOfLanguagle;

        private TrackLayer _trackLayer;

        public ElanReader(string filename)
        {
            if (File.Exists(filename) == true)
            {
                xmlDoc = new XmlDocument();
                xmlDoc.Load(filename);
                loadMediaURL(xmlDoc.DocumentElement.ChildNodes[0]);
                loadTimeStamps(xmlDoc.DocumentElement.ChildNodes[1]);
                loadLayer(xmlDoc.DocumentElement.ChildNodes[2], ref _listOfEnverment);
                loadLayer(xmlDoc.DocumentElement.ChildNodes[3], ref _listOfTransciption);
                loadLayer(xmlDoc.DocumentElement.ChildNodes[4], ref _listOfSpeaker);
                loadLayer(xmlDoc.DocumentElement.ChildNodes[5], ref _listOfLanguagle);
                loadLayer(xmlDoc.DocumentElement.ChildNodes[6], ref _listOfStoryTopic);
              
                fillTrack();



            }
            else
            {
                throw new Exception("File " + filename + " not found!");
            }


        }
        public List<string> getMediaURL()
        {
            return _mediaURL;
        }
        public List<string> MediaURL
        {
            set
            {
                _mediaURL = value;
            }
            get
            {
                return _mediaURL;
            }
        }

        public List<Segment> getTranscriptionLayer()
        {
            return _listOfTransciption;
        }
        public List<Segment> TranscriptionLayer
        {
            set { _listOfTransciption = value; }
            get
            {
                return _listOfTransciption;
            }
        }
        public List<Segment> getEnvironmentLayer()
        {
            return _listOfEnverment;
        }
        public List<Segment> EnvironmentLayer
        {
            set { _listOfEnverment = value; }
            get
            {
                return _listOfEnverment;
            }
        }
        public List<Segment> getSpeakerLayer()
        {
            return _listOfSpeaker;
        }

        public List<Segment> SpeakerLayer
        {
            set { _listOfSpeaker = value; }
            get
            {
                return _listOfSpeaker;
            }
        }

        public List<Segment> getStoryTopicLayer()
        {
            return _listOfStoryTopic;
        }
        public List<Segment> StoryTopicLayer
        {
            set { _listOfStoryTopic = value; }
            get
            {
                return _listOfStoryTopic;
            }
        }
        public List<Segment> getLanguageLayer()
        {
            return _listOfLanguagle;
        }
        public List<Segment> LanguageLayer
        {
            set { _listOfLanguagle = value; }
            get
            {
                return _listOfLanguagle;
            }
        }


        public TrackLayer TRACK
        {
            set { _trackLayer = value; }
            get { return _trackLayer; }
        }

        private int chekLayer(List<Segment> input, int testValue)
        {
            if (input[input.Count - 1].itimeend > testValue) return input[input.Count - 1].itimeend;
    
            return testValue;
        }
        private int getMaxT()
        {
            int maxt = 0;
            maxt = chekLayer(TranscriptionLayer, maxt);
            maxt = chekLayer(EnvironmentLayer, maxt);
            maxt = chekLayer(SpeakerLayer, maxt);
            maxt = chekLayer(StoryTopicLayer, maxt);
            maxt = chekLayer(LanguageLayer, maxt);

            return maxt;
            }
        private void fillTrack()
        {
            int maxTime = getMaxT()/1000;
            _trackLayer = new TrackLayer(maxTime, 5);

            _trackLayer.fillTrack(TranscriptionLayer, 0);
            _trackLayer.fillTrack(EnvironmentLayer, 1);
            _trackLayer.fillTrack(SpeakerLayer, 2);
            _trackLayer.fillTrack(StoryTopicLayer, 3);
          _trackLayer.fillTrack(LanguageLayer, 4);

        }




        private void loadMediaURL(XmlNode xNode)
        {
            _mediaURL = new List<string>();
            foreach (XmlNode xn in xNode.ChildNodes)
            {
                //  Console.WriteLine(xn.Attributes["MEDIA_URL"].Value);
                if (xn.OuterXml.Contains("MEDIA_URL="))
                {
                    _mediaURL.Add(xn.Attributes["MEDIA_URL"].Value);
                }

            }
        }
        private void loadTimeStamps(XmlNode xNode)
        {
            myTimeStamps = new Dictionary<string, string>();

            foreach (XmlNode xn in xNode.ChildNodes)
            {
                myTimeStamps.Add(xn.Attributes["TIME_SLOT_ID"].Value, xn.Attributes["TIME_VALUE"].Value);
            }
        }
        private int getTimeStamp(string input)
        {
            string rstr = "0";
            myTimeStamps.TryGetValue(input, out rstr);
            return int.Parse(rstr);
        }
        public static string getTimeString(int t)
        {
            t = t / 1000;
            return (t / 3600).ToString() + ":" + (t - t / 3600) / 60 + ":" + t % 60;

        }

        private void loadLayer(XmlNode xNode, ref List<Segment> listOfSegment)
        {
            listOfSegment = new List<Segment>();
            foreach (XmlNode xn in xNode.ChildNodes)
            {
                XmlNode subnode = xn.ChildNodes[0].ChildNodes[0];
                Segment segment = new Segment(getTimeStamp(xn.ChildNodes[0].Attributes["TIME_SLOT_REF1"].Value), getTimeStamp(xn.ChildNodes[0].Attributes["TIME_SLOT_REF2"].Value), subnode.InnerText);
                listOfSegment.Add(segment);
            }

        }




    }
}
